#pragma once

/*
    File:       SunSky.h

    Function:	Implements a sky radiance function for a clear sky

    Author:     Brian Smits (bes@phoenix.cs.utah.edu),
    			Some minor modifications by Andrew Willmott (ajw@cs.cmu.edu)

	Copyright:	(c) 1999, Brian Smits
*/
#include "DXUT.h"
#include "CommonDef.h"
#include "Spectrum.h"

class PreethamSkyLight
{
public:
    // GROUP: Constructors and assignment
    //// Default Constructor
    //    SunSky();
    //// Constructs an SunSky based on
    // [in] lat Latitude (0-360)
    // [in] long Longitude (-90,90) south to north
    // [in] sm  Standard Meridian
    // [in] jd  Julian Day (1-365)
    // [in] tod Time Of Day (0.0,23.99) 14.25 = 2:15PM
    // [in] turb  Turbidity (1.0,30+) 2-6 are most useful for clear days.
    // [in] initAtmEffects  if atm effects are not initialized, bad things will
    // happen if you try to use them....
    PreethamSkyLight(
	    	GCLReal 	lat,
	    	GCLReal 	longi,
	    	int 		sm,
	    	int 		jd,
	    	GCLReal 	tod,
	    	GCLReal 	turb,
	    	Bool		initAtmEffects = true
    );
    // GROUP: Members
    ////
    // South = x,  East = y, up = z
    Vector  	GetSunPosition() const;
    ////
    Spectrum	GetSunSpectralRadiance() const;
    ////
    GCLReal		GetSunSolidAngle() const;
    ////
    Spectrum	GetSkySpectralRadiance(const Vector &v) const;
    ////
    Spectrum	GetSkySpectralRadiance(GCLReal theta, GCLReal phi) const;

    Colour		GetSkyXYZRadiance(const Vector &v) const;
	Colour		GetSkyXYZRadiance(GCLReal theta, GCLReal phi) const;

    //// [out] theta  Sun angle down from straight above
    //   [out] phi    Sun angle anticlockwise from South
    void		GetSunThetaPhi(GCLReal &theta, GCLReal &phi) const;

    ////  Compute Atmospheric Perspective based on
    // [in] viewer  Position of the viewer
    // [in] source  Position of the distant point
    // [out] atmAttenuation Attenuation due to atmosphere
    // [out] atmInscatter   Amount of light scattered Into the viewing direction
    void 		GetAtmosphericEffects(const Vector &viewer,
                               const Vector &source,
                               Spectrum &atmAttenuation,
                               Spectrum &atmInscatter ) const;

protected:
    ////
    //    virtual GCLReal	SunLuminance() const;
    ////
    //    virtual Spectrum 	SunSpectralCurve() const;
    ////
    //    GCLReal 		SunNormalIlluminance() const;
    ////
    //    GCLReal 		SkyLuminance(const Vector &v) const;
    ////
    //    Spectrum 		SkySpectralCurve(const Vector &v) const;
private:
    //// Copy Constructor
			    SunSky(const SunSky &);
    //// Assignment
			    SunSky &operator=(const SunSky &);

    //// Compute the sun's position based on IES Sunlight Publication ????
    void 		InitSunThetaPhi();
    //// Transmittance for the sun weighted by sun's spectrum.
    Spectrum 	ComputeAttenuatedSunlight(GCLReal theta, Int turbidity);

    // GROUP:  RiAtmPerspective.C Functions
    ////
    Spectrum	AttenuationFactor(GCLReal h0, GCLReal thetav, GCLReal s) const;
    ////
    Spectrum	InscatteredRadiance(GCLReal h0, GCLReal thetav, GCLReal
                                   phiv, GCLReal s) const;
    ////
    //    Spectrum GetSkyRadiance(GCLReal theta, GCLReal phi) const;
    ////
    Spectrum	GetNeta(GCLReal theta, GCLReal v) const;
    ////
    void		CalculateA0(GCLReal thetav, GCLReal phiv, Spectrum& A0_1, Spectrum& A0_2) const;
    ////
    void		CreateConstants();
    //// Preprocessing for calculating ambient scattered light for all
    //  directions
    void		InitA0() const;
    ////
    GCLReal 	PerezFunction(const GCLReal *lam, GCLReal theta, GCLReal phi, GCLReal lvz) const;

    //Group: Data
    GCLReal 	latitude;
    GCLReal 	longitude;
    int 		julianDay;
    GCLReal 	timeOfDay;
    int 		standardMeridian;
    GCLReal 	turbidity;

    //// Sun Position Vector
    Vector 		toSun;
    //// Sun Position
    GCLReal		thetaS, phiS;
    //// Spectral Radiance computed at creation time
    Spectrum 	sunSpectralRad;
    //// Solid angle of the sun when seen from earth
    GCLReal 	sunSolidAngle;
    //// Perez data
    GCLReal 	zenith_Y, zenith_x, zenith_y;
    //// Perez coefficients
    GCLReal 	perez_Y[5], perez_x[5], perez_y[5];

    // GROUP: Constants for Atmospheric Perspective
    Spectrum 	beta_m;
    Spectrum 	beta_p;
    Spectrum 	beta_m_ang_prefix;
    Spectrum 	beta_p_ang_prefix;
    GCLReal		V;

    bool 		atmInited;
};

extern RegularSpectralCurve		solCurve;
extern IrregularSpectralCurve	k_oCurve;
extern IrregularSpectralCurve	k_gCurve;
extern IrregularSpectralCurve	k_waCurve;


